<?php

namespace App\Http\Controllers\API;

use App\Project;
use App\AwardGroup;
use App\Http\Controllers\Controller;
use App\Services\AuthService;
use App\Services\AwardService;
use App\Services\LogService;
use App\Services\CommonService;
use App\Services\ProjectService;
use App\User;
use App\WorkflowPhase;
use Request;
use Validator;


class AwardAPIController extends Controller
{
    /**
     * @var AuthService
     */
    private $authSvc;

    /**
     * @var AwardService
     */
    private $awardSvc;

    /**
     * @var LogService
     */
    private $logSvc;

    /**
     * @var CommonService
     */
    private $commonSvc;

    public function __construct()
    {
        $this->middleware('auth', [
            'except' => ['test'],
        ]);
        $this->authSvc = new AuthService;
        $this->awardSvc = new AwardService;
        $this->logSvc = new LogService;
        $this->commonSvc = new CommonService;
    }

    public function createApplication()
    {
        $data = Request::all();
        $validator = Validator::make($data, [
            'award_id' => 'required',
        ]);
        if ($validator->fails()) die; // 非正常提交
        $awardInfo = $this->awardSvc->getAwardInfo($data['award_id']);
        if (empty($awardInfo)) die;

        // 校验是否超过允许申报的个数
        $user = Request::user();
        if (!$this->awardSvc->checkUserQuota($user, $awardInfo['id'])) {
            $quota = $awardInfo['quota_per_applicant'];
            $result = ['ok' => false, 'message' => "创建失败：每位申报者只允许申报 $quota 项" . $awardInfo['name']];
            return $this->json($result);
        }

        // 校验提名信息
        if ($awardInfo['nomination_required']) {
            if (empty($data['nominator_ids'])) die; // 非正常提交
            $nominatorIds = $data['nominator_ids'];
        } else {
            $nominatorIds = [];
        }

        $application = $this->awardSvc->createApplication($user, $awardInfo['id'], $nominatorIds);
        $this->logSvc->info('创建申报', null, $user, $application);
        $result = ['ok' => true];
        return $this->json($result);
    }

    public function saveFormData()
    {
        $data = Request::all();
        if (empty($data['id'])) die;
        if (empty($data['form_data'])) die;

        //查询当前是否开启申报
        $openAwardIds = $this->awardSvc->getApplicationOpenAwardIds();
        $project = Project::find($data['id']) or die;
        $applicationPhaseEnded = !in_array($project->award_id, $openAwardIds);
        if ($applicationPhaseEnded && $project->status_id !== Project::STATUS_FORMAL_REVIEW_RETURNED_TO_FILL) {
            $result = ['ok' => false, 'message' => '申报已截止，无法提交'];
            return $this->json($result);
        }

        $user = Request::user();
        if (!$this->authSvc->canUserEditAwardApplication($user, $project)) {
            $result = ['ok' => false, 'message' => '申报书已提交，不支持修改'];
            return $this->json($result);
        }
        $this->awardSvc->saveApplicationFormData($project, $data['form_data']);
        $this->awardSvc->updateAwardProjectName($project);
        $this->logSvc->info('修改申报书', null, $user, $project);
        $result = ['ok' => true];
        return $this->json($result);
    }

    public function getApplications()
    {
        $user = Request::user();
        if (Request::has('role') && Request::get('role') == 'nominator') {
            $applications = $this->awardSvc->getUserApplications($user, 'nominator');
        } else {
            $applications = $this->awardSvc->getUserApplications($user, 'applicant');
        }
        $applicationList = $applications->toArray();
        return $this->json($applicationList);
    }

    public function getNominators()
    {
        $user = Request::user();
        $nominators = $this->awardSvc->getNominators($user);
        $nominators = $nominators->toArray();
        return $this->json($nominators);
    }

    public function applicantSubmitApplicationForm()
    {
        $data = Request::all();
        $validator = Validator::make($data, [
            'application_id' => 'required',
        ]);
        if ($validator->fails()) die; // 非正常提交
        $application = Project::find($data['application_id']);
        if (empty($application)) die;
        $user = Request::user();
        $error = $this->awardSvc->applicantSubmitApplicationForm($user, $application);
        if (!empty($error)) {
            $result = ['ok' => false, 'message' => $error];
            return $this->json($result);
        }
        $this->logSvc->info('提交形式审查', null, $user, $application);
        $result = ['ok' => true];
        return $this->json($result);
    }

    public function nominatorAgreeToNominate()
    {
        $data = Request::all();
        $validator = Validator::make($data, [
            'application_id' => 'required',
        ]);
        if ($validator->fails()) die; // 非正常提交
        $application = Project::find($data['application_id']);
        if (empty($application)) die;
        $user = Request::user();
        $error = $this->awardSvc->nominatorAgreeToNominate($user, $application);
        if (!empty($error)) {
            $result = ['ok' => false, 'message' => '操作失败：' . $error];
            return $this->json($result);
        }
        $result = ['ok' => true];
        return $this->json($result);
    }

    public function nominatorReturnApplication()
    {
        $data = Request::all();
        $validator = Validator::make($data, [
            'application_id' => 'required',
        ]);
        if ($validator->fails()) die; // 非正常提交
        $application = Project::find($data['application_id']);
        if (empty($application)) die;
        $user = Request::user();
        $error = $this->awardSvc->nominatorReturnApplication($user, $application);
        if (!empty($error)) {
            $result = ['ok' => false, 'message' => '操作失败：' . $error];
            return $this->json($result);
        }
        $this->logSvc->info('提名退回修改', null, $user, $application);
        $result = ['ok' => true];
        return $this->json($result);
    }

    // new
    public function getApplicationsByStatusId()
    {
        $data = Request::all();
        $validator = Validator::make($data, [
            'status_id' => 'required',
        ]);
        if ($validator->fails()) die; // 非正常提交
        $searchFields = [];
        if (Request::has('searchFields')) {
            $searchFields = json_decode(Request::get('searchFields'), true);
        }
        $applications = $this->awardSvc->getApplicationsByStatusId($data['status_id'], $searchFields);
        return $this->json($applications);
    }

    //删除项目
    public function deleteApplication()
    {
        $data = Request::all();
        $validator = Validator::make($data, [
            'application_id' => 'required',
        ]);
        if ($validator->fails()) die; // 非正常删除
        $user = Request::user();
        $application = Project::find($data['application_id']);
        if ($application->status_id != Project::STATUS_FORMAL_REVIEW_FILL_APPLICATION) {
            $result = ['ok' => false, 'message' => "删除失败：该奖项目前状态下不可删除"];
            return $this->json($result);
        }
        //非项目创建者和管理员不能删除
        if ($user->id != $application->user_id && $user->isAdmin() == false) {
            $result = ['ok' => false, 'message' => "无删除权限"];
            return $this->json($result);
        }
        $this->awardSvc->deleteApplicationAndFormData($application);
        $this->logSvc->info('删除申报书', null, $user, $application);
        $result = ['ok' => true];
        return $this->json($result);
    }

    //形式审查-退回项目
    public function recallApplication()
    {
        $data = Request::all();
        $validator = Validator::make($data, [
            'application_id' => 'required',
            'recall_reason' => 'required'
        ]);
        if ($validator->fails()) die; // 非正常提交
        $application = Project::find($data['application_id']);
        if (empty($application)) die;
        $recallReason = $data['recall_reason'];
        $targetStatus = Project::STATUS_FORMAL_REVIEW_RETURNED_TO_FILL;
        $user = Request::user();
        $this->awardSvc->updateApplicationStatus($application, $user, $targetStatus, $recallReason);
        $result = ['ok' => true];
        return $this->json($result);
    }

    //形式审查-通过项目
    public function applicationThroughFormalReview()
    {
        $data = Request::all();
        $validator = Validator::make($data, [
            'application_id' => 'required'
        ]);
        if ($validator->fails()) die; // 非正常提交
        $application = Project::find($data['application_id']);
        if (empty($application)) die;
        $targetStatus = Project::STATUS_ASSIGN_REVIEW_TO_ASSIGN;
        $user = Request::user();
        $this->awardSvc->updateApplicationStatus($application, $user, $targetStatus);
        $result = ['ok' => true];
        return $this->json($result);
    }

    //形式审查-提交专家初评
    public function applicationSubmitExpertReview()
    {
        $data = Request::all();
        $validator = Validator::make($data, [
            'application_id' => 'required'
        ]);
        if ($validator->fails()) die; // 非正常提交
        $application = Project::find($data['application_id']);
        if (empty($application)) die;
        $targetStatus = 'A5';
        $user = Request::user();
        $this->awardSvc->updateApplicationStatus($application, $user, $targetStatus);
        $result = ['ok' => true];
        return $this->json($result);
    }

    //项目分组
    public function createAwardGroup()
    {
        $data = Request::all();
        $validator = Validator::make($data, [
            'group_name' => 'required',
            'award_type_id' => 'required'
        ]);
        if ($validator->fails()) die;
        $user = Request::user();
        if (!$user->isAdmin()) {
            $result = ['ok' => false, 'message' => "非管理员无权创建项目分组"];
            return $this->json($result);
        }
        $sameNameAwardGroup = $this->awardSvc->getAwardGroupByGroupNameAndAwardTypeId($data['group_name'], $data['award_type_id']);
        if (!empty($sameNameAwardGroup)) {
            $result = ['ok' => false, 'message' => "该所属奖项下的分组名称已被使用，请更换其他分组名称"];
            return $this->json($result);
        }
        $this->awardSvc->createAwardGroup($data['group_name'], $data['award_type_id']);
        $result = ['ok' => true];
        return $this->json($result);
    }

    public function deleteAwardGroup()
    {
        $data = Request::all();
        $validator = Validator::make($data, [
            'group_id' => 'required',
        ]);
        if ($validator->fails()) die; // 非正常删除
        $user = Request::user();
        $group = AwardGroup::find($data['group_id']);

        if ($user->isAdmin() == false) {
            $result = ['ok' => false, 'message' => "非管理员无权删除项目分组"];
            return $this->json($result);
        }
        if ($group->isLocked()) {
            $result = ['ok' => false, 'message' => "该项目组已锁定，不可删除"];
            return $this->json($result);
        }
        $deleteType = $data['type'];
        if ($deleteType === 0) {
            $canDelete = $this->awardSvc->canDeleteAwardGroup($group);
            if (!$canDelete) {
                $result = ['ok' => true, 'message' => "该分组下已分配项目，确认删除？"];
                return $this->json($result);
            }
        }
        $this->awardSvc->deleteAwardGroup($group);
        $result = ['ok' => true];
        return $this->json($result);
    }

    public function getAwardGroupsPageData()
    {
        $data = Request::all();
        $validator = Validator::make($data, [
            'page' => 'required',
            'pageSize' => 'required',
            'filters' => 'required'
        ]);
        if ($validator->fails()) die;
        $user = Request::user();
        if (!$user->isAdmin()) {
            $result = ['ok' => false, 'message' => "非管理员无权获取"];
            return $this->json($result);
        }
        $data = $this->awardSvc->getAwardGroupsPageData($data);
        return $this->json($data);
    }

    public function getAddGroupAwardInfo()
    {
        $data = Request::all();
        $validator = Validator::make($data, [
            'group_id' => 'required',
            'award_type_id' => 'required'
        ]);
        if ($validator->fails()) die;
        $user = Request::user();
        if (!$user->isAdmin()) {
            $result = ['ok' => false, 'message' => "非管理员无权获取"];
            return $this->json($result);
        }
        $unAllocatedProjects = $this->awardSvc->getCanBeAllocatedAwards($data['filters'], $data['group_id'], $data['award_type_id']);
        $result = ['ok' => true, 'unAllocatedProjects' => $unAllocatedProjects];
        return $this->json($result);
    }

    public function getSelectedGroupAwardInfo()
    {
        $data = Request::all();
        $validator = Validator::make($data, [
            'group_id' => 'required',
            'award_type_id' => 'required'
        ]);
        if ($validator->fails()) die;
        $user = Request::user();
        if (!$user->isAdmin()) {
            $result = ['ok' => false, 'message' => "非管理员无权获取"];
            return $this->json($result);
        }
        $allocatedProjects = $this->awardSvc->getAllocatedAwards($data['filters'], $data['group_id'], $data['award_type_id']);
        $result = ['ok' => true, 'allocatedProjects' => $allocatedProjects];
        return $this->json($result);
    }

    public function importAwardsToAwardGroup()
    {
        $data = Request::all();
        $validator = Validator::make($data, [
            'group_id' => 'required',
        ]);
        if ($validator->fails()) die;
        $user = Request::user();
        if (!$user->isAdmin()) {
            $result = ['ok' => false, 'message' => "非管理员无权操作"];
            return $this->json($result);
        }
        $group = AwardGroup::find($data['group_id']);
        if ($group->isLocked()) {
            $result = ['ok' => false, 'message' => "该项目组已锁定，不可修改"];
            return $this->json($result);
        }
        $newRelationsArr = json_decode($data['new_relations'], true);
        $this->awardSvc->importAwardsToAwardGroup($data['group_id'], $newRelationsArr);
        $result = ['ok' => true];
        return $this->json($result);
    }

    public function deleteAwardsInAwardGroup()
    {
        $data = Request::all();
        $validator = Validator::make($data, [
            'group_id' => 'required',
            'delete_award_ids' => 'required'
        ]);
        if ($validator->fails()) die;
        $user = Request::user();
        if (!$user->isAdmin()) {
            $result = ['ok' => false, 'message' => "非管理员无权操作"];
            return $this->json($result);
        }
        $group = AwardGroup::find($data['group_id']);
        if ($group->isLocked()) {
            $result = ['ok' => false, 'message' => "该项目组已锁定，不可修改"];
            return $this->json($result);
        }
        $deleteAwardIds = json_decode($data['delete_award_ids'], true);
        $this->awardSvc->deleteAwardsInAwardGroupByIds($data['group_id'], $deleteAwardIds);
        $result = ['ok' => true];
        return $this->json($result);
    }

    public function updateAwardBasicInfoById()
    {
        $data = Request::all();
        $validator = Validator::make($data, [
            'group_id' => 'required',
            'target' => 'required',
        ]);
        if ($validator->fails()) die;
        $group = AwardGroup::find($data['group_id']);
        if (empty($group)) {
            return $this->json(['ok' => false, 'message' => '该项目分组不存在']);
        }
        $sameNameAwardGroup = $this->awardSvc->getAwardGroupByGroupNameAndAwardTypeId($data['target']['group_name'], $group->award_type_id);
        if (!empty($sameNameAwardGroup)) {
            $result = ['ok' => false, 'message' => "该所属奖项下的分组名称已被使用，请更换其他分组名称"];
            return $this->json($result);
        }
        $this->awardSvc->updateAwardBasicInfoById($group, $data['target']);
        return $this->json(['ok' => true]);
    }

    //项目组和评审小组绑定
    public function getAwardGroupAddExpertGroupInfo()
    {
        $data = Request::all();
        $validator = Validator::make($data, [
            'award_group_id' => 'required',
        ]);
        if ($validator->fails()) die;
        $user = Request::user();
        if (!$user->isAdmin()) {
            $result = ['ok' => false, 'message' => "非管理员无权获取"];
            return $this->json($result);
        }
        $unAllocatedExpertGroups = $this->awardSvc->getAwardGroupCanBeAllocatedExpertGroups($data['filters'], $data['award_group_id']);
        $result = ['ok' => true, 'unAllocatedExpertGroups' => $unAllocatedExpertGroups];
        return $this->json($result);
    }

    public function getAwardGroupSelectedExpertGroupInfo()
    {
        $data = Request::all();
        $validator = Validator::make($data, [
            'group_id' => 'required',
        ]);
        if ($validator->fails()) die;
        $user = Request::user();
        if (!$user->isAdmin()) {
            $result = ['ok' => false, 'message' => "非管理员无权获取"];
            return $this->json($result);
        }
        $allocatedExpertGroups = $this->awardSvc->getAwardGroupAllocatedExpertGroups($data['filters'], $data['group_id']);
        $result = ['ok' => true, 'allocatedExpertGroups' => $allocatedExpertGroups];
        return $this->json($result);
    }

    public function importExpertGroupsToAwardGroup()
    {
        $data = Request::all();
        $validator = Validator::make($data, [
            'award_group_id' => 'required',
        ]);
        if ($validator->fails()) die;
        $user = Request::user();
        if (!$user->isAdmin()) {
            $result = ['ok' => false, 'message' => "非管理员无权操作"];
            return $this->json($result);
        }
        $group = AwardGroup::find($data['award_group_id']);
        if ($group->isLocked()) {
            $result = ['ok' => false, 'message' => "该项目组已锁定，不可修改"];
            return $this->json($result);
        }
        $newRelationsArr = json_decode($data['new_relations'], true);
        $this->awardSvc->importExpertGroupsToAwardGroup($newRelationsArr);
        $result = ['ok' => true];
        return $this->json($result);
    }

    public function deleteExpertGroupsInAwardGroup()
    {
        $data = Request::all();
        $validator = Validator::make($data, [
            'award_group_id' => 'required',
            'delete_expert_group_ids' => 'required'
        ]);
        if ($validator->fails()) die;
        $user = Request::user();
        if (!$user->isAdmin()) {
            $result = ['ok' => false, 'message' => "非管理员无权操作"];
            return $this->json($result);
        }
        $group = AwardGroup::find($data['award_group_id']);
        if ($group->isLocked()) {
            $result = ['ok' => false, 'message' => "该项目组已锁定，不可修改"];
            return $this->json($result);
        }
        $deleteAwardIds = json_decode($data['delete_expert_group_ids'], true);
        $this->awardSvc->deleteExpertGroupsInAwardGroupByIds($data['award_group_id'], $deleteAwardIds);
        $result = ['ok' => true];
        return $this->json($result);
    }

    public function allocateAwardToExpertGroup()
    {
        $data = Request::all();
        $validator = Validator::make($data, [
            'award_group_id' => 'required',
        ]);
        if ($validator->fails()) die;
        $user = Request::user();
        if (!$user->isAdmin()) {
            $result = ['ok' => false, 'message' => "非管理员无权操作"];
            return $this->json($result);
        }
        $group = AwardGroup::find($data['award_group_id']);
        if ($group->isLocked()) {
            $result = ['ok' => false, 'message' => "该项目组已锁定，不可修改"];
            return $this->json($result);
        }
        $error = $this->awardSvc->allocateAwardToExpertGroup($group);
        if (!empty($error)) {
            $result = ['ok' => false, 'message' => $error];
            return $this->json($result);
        }
        $result = ['ok' => true];
        return $this->json($result);
    }

    public function getAwardGroupReviewArrangementInfo()
    {
        $data = Request::all();
        $validator = Validator::make($data, [
            'award_group_id' => 'required',
        ]);
        if ($validator->fails()) die;
        $user = Request::user();
        if (!$user->isAdmin()) {
            $result = ['ok' => false, 'message' => "非管理员无权操作"];
            return $this->json($result);
        }
        $group = AwardGroup::find($data['award_group_id']);
        $info = $this->awardSvc->getAwardGroupReviewArrangementInfo($group);
        $result = ['ok' => true, 'info' => $info];
        return $this->json($result);
    }

    public function getAwardedProjects()
    {
        $largeGroupId = Request::get('large_group_id');
        $result = (new ProjectService())->getAwardedProjects($largeGroupId);
        return $this->json($result);
    }
}
